#include "myjni.h"
#include "platform_config.h"
#include <termios.h>
#include <sys/epoll.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <pthread.h>
#include <time.h>
#include <unistd.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <sys/time.h>
#include "minizip/unzip.h"
#include "utf8-unicode.h"
int fd_pri;
int epoll_threadfd;
int cmd_fd;
int Adc_fd;
int fd_led;
extern SysInf  SysInfor;
extern int threadSocketW;
int disp_set_para = 0;
static pthread_mutex_t mutex_gpsData_lock = PTHREAD_MUTEX_INITIALIZER;
static pthread_mutex_t mutex_log_lock = PTHREAD_MUTEX_INITIALIZER;
static pthread_mutex_t mutex_block_rw = PTHREAD_MUTEX_INITIALIZER;
extern char SMSReceiveBuffer[BUFFER_SIZE];
extern unsigned char GPRSLink_Flag;
static int adc_uart_fd = -1, epoll_Adc_fd = -1;
int area_fd, priv_fd, gps_fd;
extern int flag_login;
static int adc_error = -1;
extern int localSocketR, localSocketW;
static unsigned short adcvalue = 0;
static long interval_in_useconds = 6000000;

static int epoll_register(int epoll_fd, int fd) {
    struct epoll_event  ev;
    int ret, flags;

    /* important: make the fd non-blocking */
    flags = fcntl(fd, F_GETFL);
    fcntl(fd, F_SETFL, flags | O_NONBLOCK);

    ev.events  = EPOLLIN;
    ev.data.fd = fd;
    do {
        ret = epoll_ctl(epoll_fd, EPOLL_CTL_ADD, fd, &ev);
    } while (ret < 0 && errno == EINTR);
    LOGE("%s, fd=%d", __func__, fd);
    return ret;
}

int epoll_deregister(int epoll_fd, int fd) {
    int  ret;
    do {
        ret = epoll_ctl(epoll_fd, EPOLL_CTL_DEL, fd, NULL);
    } while (ret < 0 && errno == EINTR);
    return ret;
}

int set_baudrate(const int fd, const char *bautrate) {
    struct termios ntermios;
    int speed_B[]={B1200, B2400, B4800, B9600, B19200, B38400, B57600, B115200, B230400, B921600};
    const char  *speed_arr[]={"B1200", "B2400", "B4800", "B9600", "B19200", "B38400", "B57600", "B115200", "B230400", "B921600"};
    uint32_t i;
    int err = -1;

    for (i = 0; i < sizeof(speed_B) / sizeof(speed_B[0]); i++) {
        if(!memcmp(bautrate, speed_arr[i], strlen(bautrate))) {
            err = 0;
            LOGE("set_baudrate = %d\n", speed_B[i]);
            tcflush(fd, TCIOFLUSH);
            if ((err = tcgetattr(fd,&ntermios)) != 0)
            {
                LOGE("tcgetattr(%d) = %d,errno %d\r\n", fd, err, errno);
                close(fd);
                return err;

            }
            ntermios.c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP|INLCR|IGNCR|ICRNL|IXON);
            ntermios.c_oflag &= ~OPOST;
            ntermios.c_lflag &= ~(ECHO|ECHONL|ICANON|ISIG|IEXTEN);
            ntermios.c_cflag &= ~(CSIZE|PARENB);
            ntermios.c_cflag |= CS8;
            ntermios.c_cflag &= ~CRTSCTS;//no flow control
            tcsetattr(fd, TCSANOW, &ntermios);
            tcflush(fd, TCIOFLUSH);
            tcflush(fd, TCIOFLUSH);
            tcflush(fd, TCIOFLUSH);
            err = cfsetispeed(&ntermios, speed_B[i]);
            if (err)
            {
                LOGE("cfsetispeed.. errno..\r\n");
                close(fd);
                return err;
            }
            err = cfsetospeed(&ntermios, speed_B[i]);
            if (err)
            {
                LOGE("cfsetispeed.. errno..\r\n");
                close(fd);
                return err;
            }
            tcsetattr(fd,TCSANOW,&ntermios);
        }
    }
    return err;
}


static char *para_ip_index[4] = {
    "ip",
    "port",
    "terminalId",
    "carNum",
};

#define LINEAR_LIST "linearList="

int checkExFile() {
    int flags = 0;
    char path[64] = {0};
    unsigned int i = 0;
    char buf[255];
    FILE *fp;
    int found = -1;
    SysInf *p_sys = &SysInfor;

    sprintf(path, "/storage/sdcard1/%s", EX_PRIVATE_PAR);
    if (access(path, F_OK)) {
        return found;
    }
    fp = fopen(path, "r");
    if (fp == NULL)
        return found;
    char para[5][64];
    int ret;
    char *p_start, *p_end;

    memset(buf, 0, sizeof(buf));
    while (fgets(buf, sizeof(buf), fp)) {
        //LOGE("buf[0]=%c,%c,%c,%c,", buf[0], buf[1], buf[2], buf[3]);
         LOGE("para buf:%s", buf);
         if (strstr(buf, "#"))
             continue;
         memset(para, 0, sizeof(para));
         p_start = strstr(buf, "ip=");
         if (p_start) {
             for (i = 0; i < sizeof_arry(para_ip_index); i++) {
                 p_start = strstr(p_start, para_ip_index[i]);
                 if (p_start == NULL)
                     break;
                 p_start += strlen(para_ip_index[i]) + 1;
                 p_end = strchr(p_start, ';');
                 if (!p_end)
                     p_end = strchr(p_start, '\n');
                 strncpy(para[i], p_start, p_end - p_start);
                 p_start = p_end;
                 LOGE("para[%d]:%s", i, para[i]);
             }
             if (i == sizeof_arry(para_ip_index)) {
                 memset(p_sys->IP, 0, 30);
                 memset(p_sys->terminalID, 0, sizeof(p_sys->terminalID));
                 memset(p_sys->LocalPhoneNum1, 0, sizeof(p_sys->LocalPhoneNum1));
                 memset(p_sys->CarNumber, 0, sizeof(p_sys->CarNumber));
                 memset(p_sys->CarNumber_utf8, 0, sizeof(p_sys->CarNumber_utf8));
                 sprintf(p_sys->IP,"%s", para[0]);
                 p_sys->port = atoi(para[1]);
                 sprintf(p_sys->terminalID, "%s", para[2]);
                 sprintf(p_sys->LocalPhoneNum1, "01861%s", para[2]);
                 p_sys->IP[sizeof(p_sys->IP) - 1] = 0; //防止参数过长溢出
                 p_sys->terminalID[sizeof(p_sys->terminalID) - 1] = 0;
                 p_sys->LocalPhoneNum1[sizeof(p_sys->LocalPhoneNum1) - 1] = 0;

                 int unicode;
                 char *p_int = (char *)&unicode;
                 strcpy(p_sys->CarNumber_utf8, para[3]);
                 int u_len = UTF8toUnicode((unsigned char *)para[3], &unicode);
                 sprintf(p_sys->CarNumber + 2, "%s", para[3] + u_len);
                 p_sys->CarNumber[sizeof(p_sys->CarNumber) - 1] = 0; //防止参数过长溢出
                 p_sys->CarNumber[0] = p_int[1];
                 p_sys->CarNumber[1] = p_int[0];

                 GPRSLink_Flag = 0; //reconnect network
                 flag_login = 0; //re login
                 led_4g_offline();
                 disp_set_para = 1;
                 write_log_to_sdcard("sdcard:设置IP参数");
                 at24c64Write(priv_fd, SYSINFO_SET, (void *)&SysInfor, SysInfLength);
             }
             continue;
         }
         p_start = strstr(buf, LINEAR_LIST);
         if (p_start) {
             char *linearList = buf + strlen(LINEAR_LIST);
             u16 buf[10];
             sscanf(linearList, "%hd,%hd; %hd,%hd; %hd,%hd; %hd,%hd; %hd,%hd;", buf, buf+1, buf+2, buf+3, buf+4, buf+5, buf+6, buf+7, buf+8, buf+9);
             LOGE("sdcard set linearList parameter:");
             for (i = 0; i < 10; i++)
                 LOGE("%hd", buf[i]);
             memcpy((void *)SysInfor.str_linearList, buf, sizeof(buf));
             at24c64Write(priv_fd, SYSINFO_SET, (void *)&SysInfor, SysInfLength);
             write_log_to_sdcard("sdcard:设置水位参数");
             continue;
         }
    }
    fclose(fp);

    return 1;
}

void split(char *buf) {
    char *ptr;
    char *p;
    char *data[10];
    int i = 0;

    memset(data, 0, sizeof(data));
    ptr = strtok(buf, ";");
    while (ptr) {
        LOGE("%s", ptr);
        data[i] = strdup(ptr);
        ptr = strtok(NULL, ";");
        if (++i >= 10)
            break;
    }
    for (i = 0; (i < 10) && data[i]; i++) {
        p = strstr(data[i], "car=");
        if (p) {
            p += 4;
            if (strlen(p) >= sizeof(SysInfor.CarNumber))
                continue;
            memset(SysInfor.CarNumber_utf8, 0, sizeof(SysInfor.CarNumber_utf8));
            memset(SysInfor.CarNumber, 0, sizeof(SysInfor.CarNumber));
            strcpy(SysInfor.CarNumber_utf8, p);
            int unicode;
            char *p_int = (char *)&unicode;
            int u_len = UTF8toUnicode((unsigned char *)p, &unicode);
            sprintf(SysInfor.CarNumber + 2, "%s", p + u_len);
            SysInfor.CarNumber[0] = p_int[1];
            SysInfor.CarNumber[1] = p_int[0];
            write_log_to_sdcard("短信设置车牌号");
            continue;
        } 
        p = strstr(data[i], "port=");
        if (p) {
            p += 5;
            SysInfor.port = atoi(p);
            write_log_to_sdcard("短信设置IP");
            continue;
        }
        p = strstr(data[i], "id=");
        if (p) {
            p += 3;
            if (strlen(p) >= sizeof(SysInfor.terminalID))
                continue;
            memset(SysInfor.terminalID, 0, sizeof(SysInfor.terminalID));
            strcpy(SysInfor.terminalID, p);
            memset(SysInfor.LocalPhoneNum1, 0, sizeof(SysInfor.LocalPhoneNum1));
            sprintf(SysInfor.LocalPhoneNum1, "01861%s", p);
            write_log_to_sdcard("短信设置终端号");
            continue;
        }
        p = strstr(data[i], "ip=");
        if (p) {
            p += 3;
            if (strlen(p) >= sizeof(SysInfor.IP))
                continue;
            memset(SysInfor.IP, 0, sizeof(SysInfor.IP));
            strcpy(SysInfor.IP, p);
            continue;
        }

    }
    for (i = 0; (i < 10) && data[i]; i++)
        free(data[i]);

    disp_set_para = 1;
    at24c64Write(priv_fd, SYSINFO_SET, (void *)&SysInfor, SysInfLength);
}

int at24c64Read(int fd, int set, void *buf,int Length) {
    char md5[33];
    int i, found = 0;
    int ret = -1;

    blockRead(fd, set, buf, Length);
    Compute_buf_md5(buf, md5, Length - sizeof(md5));
    //LOGE("%s source_md5=%s md5=%s, magic=%x", __func__, ((SysInf *)buf)->md5, md5, ((SysInf *)buf)->magic);
    if(memcmp(((SysInf *)buf)->md5, md5, sizeof(md5))) {
        LOGE("device md5 check fail, try at24c64");
        i = 0;
        while (i++ < 3) {
            if (at24c64_read(set, Length, buf) == 0) {
                Compute_buf_md5(buf, md5, Length - sizeof(md5));
                if(memcmp(((SysInf *)buf)->md5, md5, sizeof(md5))) {
                    LOGE("at24c64 md5 check fail, retry");
                } else {
                    LOGE("at24c64 md5 check success");
                    blockWrite(fd, set, buf, Length);
                    ret = 0;
                    break;
                }
            }
            sleepMsec(200);
        }
    } else {
        ret = 0;
        LOGE("%s md5 chek sucess", __func__);
    }
    return ret;
}

int at24c64Write(int fd, int set, void *buf,int Length) {
    char md5[33];
    int ret, i;

    Compute_buf_md5(buf, md5, Length - sizeof(md5));
    memcpy(((SysInf *)buf)->md5, md5, sizeof(md5));
    //LOGE("%s md5=%s", __func__, ((SysInf *)buf)->md5);
    i = 0;
    while (i++ < 3) {
        at24c64_write(set, Length, buf);
        sleepMsec(200);
    }
    ret = blockWrite(fd, set, buf, Length);

    return ret;
}

int blockRead(int fd, int set, void *buf,int Length) {
    if (fd < 0)
        return -1;
    pthread_mutex_lock(&mutex_block_rw);
    lseek(fd, set, SEEK_SET);
    read(fd, buf, Length);
    pthread_mutex_unlock(&mutex_block_rw);
    return 0;
}

int blockWrite(int fd, int set, void *buf,int Length) {
    if (fd < 0)
        return -1;
    pthread_mutex_lock(&mutex_block_rw);
    lseek(fd, set, SEEK_SET);
    write(fd, buf, Length);
    pthread_mutex_unlock(&mutex_block_rw);
    return 0;
}

int block_init(char *path, unsigned int len) {
    int fd = -1;

    if (access(path, F_OK)) {
        creat(path, S_IRWXO);
        chmod(path, S_IROTH|S_IWOTH|S_IRGRP|S_IWGRP|S_IRWXU|S_IRWXO|S_IRWXG);
        fd = open(path, O_RDWR);
        if (fd < 0) {
            LOGE("open %s fail, err= %s\n", path, strerror(errno));
            return -1;
        }
        lseek(fd, 0, SEEK_SET);
        unsigned int i;
        unsigned int val = 0;
        for (i = 0; i < len; i+=4)
            write(fd, &val, sizeof(val));
        return fd;
    }
    fd = open(path, O_RDWR);
    if (fd < 0) {
        LOGE("open %s fail, err= %s\n", path, strerror(errno));
        return -1;
    }
    return fd;
}


static int gpio_fd = 0;
#define LED_LIGHT -1
#define LED_OFF -2
GPIO_CTL red_led = {LED_RED, 0, LED_LIGHT, 0}, green_led = {LED_GREEN, 0, LED_OFF, 0};
#define HZ(x) (500/x)
static void write_gpio() {
    if(gpio_fd < 0) {
        return;
    }
    write(gpio_fd, &red_led, sizeof(GPIO_CTL));
    sleepMsec(250);
    write(gpio_fd, &green_led, sizeof(GPIO_CTL));
}

void led_4g_online(void) { //红灯1HZ闪烁
    red_led.time_interval = adc_error ? HZ(5) : HZ(1);
    write_gpio(); 
}

void led_gps_online(void) { //绿灯1HZ闪烁
    green_led.time_interval = HZ(1);
    write_gpio(); 
}

void led_4g_offline(void) { //红灯常亮
    red_led.time_interval = adc_error ? HZ(5) : LED_LIGHT;//红灯亮表示设备在工作
    write_gpio(); 
}

void led_gps_offline(void) { //绿灯灭
    green_led.time_interval = LED_OFF;
    write_gpio(); 
}

void led_adc_error(void) { //红灯快闪烁
    red_led.time_interval = HZ(5);
    write_gpio(); 
}

void led_adc_normal(void) { //恢复红灯原来状态
    red_led.time_interval = flag_login ? HZ(1) : LED_LIGHT;
    write_gpio(); 
}


void led_enter_test_mode() {
    red_led.time_interval = LED_OFF;
    green_led.time_interval = LED_OFF;
    write_gpio(); 
}

void led_test_ok() {
    red_led.time_interval = LED_LIGHT;
    green_led.time_interval = LED_LIGHT;
    write_gpio(); 
}

void led_gps_error() {
    green_led.time_interval = HZ(8);
    write_gpio(); 
}

void led_4g_error() {
    red_led.time_interval = HZ(8);
    write_gpio(); 
}


void led_adc_disp_check() {
    int adc = adcvalue;
    while(1) {
        if (abs(adc-adcvalue) > 30)
            break;
        adc = adcvalue;
        sleepMsec(100);
    }
}

void led_adc_disp() {
    int interval = MAX(1, adcvalue*500/4096);
    //red_led.time_interval = interval;
    green_led.time_interval = interval;
    write_gpio(); 
}


int open_gpio() {
    gpio_fd = open("/dev/gpio_ctl", O_RDWR);
    if (gpio_fd < 0) {
        ALOGE("open /dev/gpio_ctl fail");
        return -1;
    }
    return gpio_fd;
}

void close_gpio() {
    if (gpio_fd > 0)
        close(gpio_fd);
    gpio_fd = 0;
}

#define LOG_SERVER_IP "120.78.192.121"
#define LOG_SERVER_PORT 54322
#define LOG_BUF_MAX (2*1024*1024)
char *gps_info_buf = NULL, *sdcard_log_buf = NULL;
static unsigned int gps_info_buf_len = 0, sdcard_log_buf_len = 0;
void write_gps_info(const char *fmt, ...) {
#if 0
    va_list ap;
    pthread_mutex_lock(&mutex_gpsData_lock);
    if (!gps_info_buf) {
        gps_info_buf = malloc(LOG_BUF_MAX);
        gps_info_buf_len = 0;
        memset(gps_info_buf, 0, LOG_BUF_MAX);
    }
    va_start(ap, fmt);
    vsnprintf(gps_info_buf + gps_info_buf_len, LOG_BUF_MAX, fmt, ap);
    va_end(ap);
    strcat(gps_info_buf, "\r\t");
    gps_info_buf_len += strlen(gps_info_buf);
    pthread_mutex_unlock(&mutex_gpsData_lock);
#endif
    FILE *fp;
    char buf[1024];
    va_list ap; 
    long ts; 
    char time_str[128];
    struct tm *tm;

    pthread_mutex_lock(&mutex_gpsData_lock);
    ts = time(NULL);
    tm = localtime(&ts);
    va_start(ap, fmt);
    vsnprintf(buf, sizeof(buf), fmt, ap);
    va_end(ap);
    sprintf(time_str, "%d-%02d-%02d %02d:%02d:%02d  ", (1900+tm->tm_year), 1+tm->tm_mon, tm->tm_mday, tm->tm_hour, tm->tm_min, tm->tm_sec);
    fp = fopen(GPS_DATA_LOG_PATH, "at+");
    if (!fp) {
        LOGE("open gpsData.txt error[%s], quit", strerror(errno));
        if (strlen(gps_info_buf) + strlen(time_str) + strlen(buf) < LOG_BUF_MAX - 4) {
            strcat(gps_info_buf, time_str);
            strcat(gps_info_buf, buf);
            strcat(gps_info_buf, "\r\n");
        }
        goto out;
    }   
    if (strlen(gps_info_buf) > 0) {
        fwrite(gps_info_buf, 1, strlen(gps_info_buf), fp);
        memset(gps_info_buf, 0, LOG_BUF_MAX);
    }
    fwrite(time_str, 1, strlen(time_str), fp);
    fwrite(buf, 1, strlen(buf), fp);
    fwrite("\r\n", 1, 2, fp);
    fclose(fp);
out:
    pthread_mutex_unlock(&mutex_gpsData_lock);
    write_log_to_sdcard(buf);

}

void write_log_to_sdcard(const char *fmt, ...) {
#if 0
    va_list ap;
    u32 num;
    
    pthread_mutex_lock(&mutex_log_lock);
    if (!sdcard_log_buf) {
        sdcard_log_buf = malloc(LOG_BUF_MAX);
        sdcard_log_buf_len = 0;
        memset(sdcard_log_buf, 0, LOG_BUF_MAX);
    }
    va_start(ap, fmt);
    vsnprintf(sdcard_log_buf + sdcard_log_buf_len, LOG_BUF_MAX, fmt, ap);
    va_end(ap);
    strcat(sdcard_log_buf, "\r\t");
    sdcard_log_buf_len += strlen(sdcard_log_buf);
    pthread_mutex_unlock(&mutex_log_lock);
#endif
    FILE *fp;
    long ts; 
    va_list ap; 
    char buf[1024];
    char time_str[128];
    struct tm *tm;

    pthread_mutex_lock(&mutex_log_lock);
    ts = time(NULL);
    tm = localtime(&ts);
    va_start(ap, fmt);
    vsnprintf(buf, sizeof(buf), fmt, ap);
    va_end(ap);

    sprintf(time_str, "%d-%02d-%02d %02d:%02d:%02d  ", (1900+tm->tm_year), 1+tm->tm_mon, tm->tm_mday, tm->tm_hour, tm->tm_min, tm->tm_sec);
    fp = fopen(LOG_TXT_PATH, "at+");
    if (!fp) {
        if (strlen(sdcard_log_buf) + strlen(buf) + strlen(time_str) < LOG_BUF_MAX - 4) {
            strcat(sdcard_log_buf, time_str);
            strcat(sdcard_log_buf, buf);
            strcat(sdcard_log_buf, "\r\n");
        }
        goto out;
    }   
    if (strlen(sdcard_log_buf) > 0) {
        fwrite(sdcard_log_buf, 1, strlen(sdcard_log_buf), fp);
        memset(sdcard_log_buf, 0, LOG_BUF_MAX);
    }
    fwrite(time_str, 1, strlen(time_str), fp);
    fwrite(buf, 1, strlen(buf), fp);
    fwrite("\r\n", 1, 2, fp);
    fclose(fp);
out:
    pthread_mutex_unlock(&mutex_log_lock);

}

void init_log_buf() {
    gps_info_buf = malloc(LOG_BUF_MAX);
    memset(gps_info_buf, 0, LOG_BUF_MAX);
    sdcard_log_buf = malloc(LOG_BUF_MAX);
    memset(sdcard_log_buf, 0, LOG_BUF_MAX);
}

void free_log_buf() {
    if (gps_info_buf)
        free(gps_info_buf);
    if (sdcard_log_buf)
        free(sdcard_log_buf);
}


int upload_log_to_server(void) {
    struct sockaddr_in server_addr;
    struct timeval timeo = {3, 0};
    int s;
    unsigned int send_len;

    LOGE("%s", __func__);
    s = socket(AF_INET, SOCK_STREAM, 0);
    if (s <= 0) {
        LOGE("create socket fail[%s]", strerror(errno));
        return -1;
    }
    //设置服务器地址
    bzero(&server_addr, sizeof(server_addr));
    server_addr.sin_family = AF_INET;
    server_addr.sin_addr.s_addr = inet_addr(LOG_SERVER_IP);
    server_addr.sin_port = htons(LOG_SERVER_PORT);
    //inet_pton(AF_INET, LOG_SERVER_IP, &server_addr.sin_addr);
    setsockopt(s, SOL_SOCKET, SO_SNDTIMEO, &timeo, (socklen_t)sizeof(timeo));
    int reuse = 1;
    setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse));
    if (connect(s, (struct sockaddr *)&server_addr, sizeof(server_addr)) == -1) {
        LOGE("%s connect fail[%d][%s]", __func__, errno, strerror(errno));
        goto out;
    }
    int block_flag = fcntl(s, F_GETFL);
    if(block_flag < 0) {
        LOGE("get socket fd flag error:%s\n", strerror(errno));
        goto out;
    } else {
        if(fcntl(s, F_SETFL, block_flag | O_NONBLOCK) < 0){
            LOGE("set socket fd non block error:%s\n", strerror(errno));
            goto out;
        }
    }

    pthread_mutex_lock(&mutex_gpsData_lock);
    send_len = 0;
    while (send_len < gps_info_buf_len) {
        int len = send(s, gps_info_buf + send_len, gps_info_buf_len - send_len, 0);
        if (len < 0) {
            if (errno == EINTR) continue;
            ALOGE("send gps info log to server error: %s\n", strerror(errno));
            break;
        }
        send_len += len;
    }
    gps_info_buf_len = 0;
    pthread_mutex_unlock(&mutex_gpsData_lock);

    pthread_mutex_lock(&mutex_log_lock);
    send_len = 0;
    while (send_len < sdcard_log_buf_len) {
        int len = send(s, sdcard_log_buf + send_len, sdcard_log_buf_len - send_len, 0);
        if (len < 0) {
            if (errno == EINTR) continue;
            ALOGE("send sdcard log to server error: %s\n", strerror(errno));
            break;
        }
        send_len += len;
    }
    sdcard_log_buf_len = 0;
    pthread_mutex_unlock(&mutex_log_lock);

out:
    shutdown(s, SHUT_RDWR);
    close(s);
    return 0;
}




int openAdcUart(char *path, int flags) {
    adc_uart_fd = open(path, flags > 0 ? flags : O_RDWR | O_NOCTTY | O_NDELAY);
    if (adc_uart_fd <= 0) {
        ALOGE("open fd err[%s, %s]\n", path, strerror(errno));
        return -1;
    }
    ALOGE("open %s sucess, fd = %d\n", path, adc_uart_fd);

    set_baudrate(adc_uart_fd, "B115200");

    epoll_Adc_fd = epoll_create(2);
    epoll_register(epoll_Adc_fd, adc_uart_fd);

    return 0;
}

int register_local_socket(int fd) {
    return epoll_register(epoll_Adc_fd, fd);
}


void closeAdcUart(void) {
    if (adc_uart_fd > 0) {
        epoll_deregister(epoll_Adc_fd, adc_uart_fd);
        close(epoll_Adc_fd);
        close(adc_uart_fd);
    }
}

extern volatile int threadRuning;
u32 g_currentAdValue = 0;
static u32 adc_sum = 4096;
static u32 adc_counter = 0;
static int IOIN1_pwm = 0, IOIN2_pwm = 0;
unsigned long int IOIN1_pwm_sum = 0, IOIN2_pwm_sum = 0;

long currentTimeInSec() {
    struct timeval tv;
    gettimeofday(&tv, NULL);
    return tv.tv_sec + tv.tv_usec/1000000;
}

long currentTimeInMsec() {
    struct timeval tv;
    gettimeofday(&tv, NULL);
    return tv.tv_sec*1000 + tv.tv_usec/1000;
}

long currentTimeInUsec() {
    struct timeval tv;
    gettimeofday(&tv, NULL);
    return tv.tv_sec*1000000 + tv.tv_usec;
}

void *readAdcUart(void *arg) {//patch_sensor_msg
    struct epoll_event events[2];
    int nevents;
    struct timeval tv; 
    int count = 0, i, num;
    unsigned char buf[10];
    long time1, time2;
    int ne;
    int localValue;
    unsigned bufw[1] = {0xab};

    if (epoll_Adc_fd <= 0)
        return NULL;

    time1 = currentTimeInMsec();
    while (1) {
        nevents = epoll_wait(epoll_Adc_fd, events, 2, 10000);
        if (nevents == 0) {
            LOGE("Adc uart timeout");
            continue;
        }
        for (ne = 0; ne < nevents; ne++) {
            if ((events[ne].events & EPOLLIN) == 0)
                continue;
            if (events[ne].data.fd == adc_uart_fd) {
                count = read(adc_uart_fd, buf, 10); 
                if (count == 4) {
                    adcvalue = (unsigned short)(buf[0] | (buf[1] << 8));
		    LOGE("adc********adcvalue = %d", adcvalue);
                    adc_sum += adcvalue;
                    adc_counter++;
                    IOIN1_pwm_sum = buf[2];
                    IOIN2_pwm_sum = buf[3];
					g_sumOfPwm += IOIN1_pwm_sum + IOIN2_pwm_sum;
                    LOGE("adc=%d IOIN1_pwm=%lu, IOIN2_pwm=%lu", adcvalue, IOIN1_pwm_sum, IOIN2_pwm_sum);
                }
                write(adc_uart_fd, bufw, 1); 
            } else if (events[ne].data.fd == localSocketR) {
                count = read(localSocketR, &localValue, sizeof(localValue));
                if (count == sizeof(localValue)) {
                    switch (localValue) {
                        case AIRPLANE:
                            {
                                power_detect_work();
                            } break;
                        case ADC_PWM_AVERAGE: 
                            {
                                g_currentAdValue = adc_sum / MAX(1, adc_counter);
                                adc_counter = 0;
                                adc_sum = 0;

                                LOGE("adc val=%d", g_currentAdValue);
                                LOGE("pwm1=%d pwm2=%d", IOIN1_pwm/6, IOIN2_pwm/6);//pwm每秒平均值
                            } break;

                    }
                }
            }
        }
    }

    return NULL;
}


static void adcAverage(int signo) {
    int value = ADC_PWM_AVERAGE;
    write(localSocketW, &value, sizeof(value));
}

void adcTimer(void) {//6seconds计算一次平均值
    struct itimerval itv;
    itv.it_interval.tv_sec = interval_in_useconds/1000000;
    itv.it_interval.tv_usec = interval_in_useconds%1000000;
    itv.it_value.tv_sec = 1;//1秒钟后开始,触发定时器，以后每次将it_interval装载到it_value中
    itv.it_value.tv_usec = 0;
    signal(SIGALRM, adcAverage);
    setitimer(ITIMER_REAL, &itv, NULL);
}


void cancelAdcTimer(void) {
    struct itimerval itv;
    itv.it_interval.tv_sec = 0;
    itv.it_interval.tv_usec = 0;
    itv.it_value.tv_sec = 0;
    itv.it_value.tv_usec = 1;
    signal(SIGALRM, adcAverage);
    setitimer(ITIMER_REAL, &itv, NULL);
}
